home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 83 / MacAddict_083_2003-07.iso / mac / Software / Development / VLC Source 0.5.3.dmg / src / misc / modules_plugin.h.in < prev    next >
Text File  |  2003-04-07  |  8KB  |  227 lines

  1. /*****************************************************************************
  2.  * modules_plugin.h : Plugin management functions used by the core application.
  3.  *****************************************************************************
  4.  * Copyright (C) 2001 VideoLAN
  5.  * $Id: modules_plugin.h.in,v 1.9 2003/02/10 20:11:14 sam Exp $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23.  
  24. /*****************************************************************************
  25.  * Inline functions for handling dynamic modules
  26.  *****************************************************************************/
  27.  
  28. /*****************************************************************************
  29.  * module_load: load a dynamic library
  30.  *****************************************************************************
  31.  * This function loads a dynamically linked library using a system dependant
  32.  * method, and returns a non-zero value on error, zero otherwise.
  33.  *****************************************************************************/
  34. static int module_load( const MYCHAR * psz_filename, module_handle_t * handle )
  35. {
  36. #ifdef SYS_BEOS
  37.     *handle = load_add_on( psz_filename );
  38.     return( *handle < 0 );
  39.  
  40. #elif defined(WIN32) || defined(UNDER_CE)
  41.     *handle = LoadLibrary( psz_filename );
  42.     return( *handle == NULL );
  43.  
  44. #elif defined(RTLD_NOW)
  45.     /* static is OK, we are called atomically */
  46.     static vlc_bool_t b_kde = VLC_FALSE;
  47.  
  48. #   if defined(SYS_LINUX)
  49.     /* XXX HACK #1 - we should NOT open modules with RTLD_GLOBAL, or we
  50.      * are going to get namespace collisions when two modules have common
  51.      * public symbols, but ALSA is being a pest here. */
  52.     if( strstr( psz_filename, "alsa_plugin" ) )
  53.     {
  54.         *handle = dlopen( psz_filename, RTLD_NOW | RTLD_GLOBAL );
  55.         return( *handle == NULL );
  56.     }
  57. #   endif
  58.     /* XXX HACK #2 - the ugly KDE workaround. It seems that libkdewhatever
  59.      * causes dlopen() to segfault if libstdc++ is not loaded in the caller,
  60.      * so we just load libstdc++. Bwahahaha! ph34r! -- Sam. */
  61.     if( !b_kde && !strstr( psz_filename, "kde" ) )
  62.     {
  63.         dlopen( "libstdc++.so.6", RTLD_NOW )
  64.          || dlopen( "libstdc++.so.5", RTLD_NOW )
  65.          || dlopen( "libstdc++.so.4", RTLD_NOW )
  66.          || dlopen( "libstdc++.so.3", RTLD_NOW );
  67.         b_kde = VLC_TRUE;
  68.     }
  69.  
  70.     *handle = dlopen( psz_filename, RTLD_NOW );
  71.     return( *handle == NULL );
  72.  
  73. #else
  74.     *handle = dlopen( psz_filename, DL_LAZY );
  75.     return( *handle == NULL );
  76.  
  77. #endif
  78. }
  79.  
  80. /*****************************************************************************
  81.  * module_unload: unload a dynamic library
  82.  *****************************************************************************
  83.  * This function unloads a previously opened dynamically linked library
  84.  * using a system dependant method. No return value is taken in consideration,
  85.  * since some libraries sometimes refuse to close properly.
  86.  *****************************************************************************/
  87. static void module_unload( module_handle_t handle )
  88. {
  89. #ifdef SYS_BEOS
  90.     unload_add_on( handle );
  91.  
  92. #elif defined(WIN32) || defined(UNDER_CE)
  93.     FreeLibrary( handle );
  94.  
  95. #else
  96.     dlclose( handle );
  97.  
  98. #endif
  99.     return;
  100. }
  101.  
  102. /*****************************************************************************
  103.  * module_getsymbol: get a symbol from a dynamic library
  104.  *****************************************************************************
  105.  * This function queries a loaded library for a symbol specified in a
  106.  * string, and returns a pointer to it. We don't check for dlerror() or
  107.  * similar functions, since we want a non-NULL symbol anyway.
  108.  *****************************************************************************/
  109. static void * _module_getsymbol( module_handle_t handle,
  110.                                  const char * psz_function )
  111. {
  112. #ifdef SYS_BEOS
  113.     void * p_symbol;
  114.     if( B_OK == get_image_symbol( handle, psz_function,
  115.                                   B_SYMBOL_TYPE_TEXT, &p_symbol ) )
  116.     {
  117.         return p_symbol;
  118.     }
  119.     else
  120.     {
  121.         return NULL;
  122.     }
  123.  
  124. #elif defined( UNDER_CE )
  125.     wchar_t psz_real[256];
  126.     MultiByteToWideChar( CP_ACP, 0, psz_function, -1, psz_real, 256 );
  127.  
  128.     return (void *)GetProcAddress( handle, psz_real );
  129.  
  130. #elif defined( WIN32 )
  131.     return (void *)GetProcAddress( handle, (MYCHAR*)psz_function );
  132.  
  133. #else
  134.     return dlsym( handle, psz_function );
  135.  
  136. #endif
  137. }
  138.  
  139. static void * module_getsymbol( module_handle_t handle,
  140.                                 const char * psz_function )
  141. {
  142.     void * p_symbol = _module_getsymbol( handle, psz_function );
  143.  
  144.     /* MacOS X dl library expects symbols to begin with "_". So do
  145.      * some other operating systems. That's really lame, but hey, what
  146.      * can we do ? */
  147.     if( p_symbol == NULL )
  148.     {
  149.         char *psz_call = malloc( strlen( psz_function ) + 2 );
  150.  
  151.         strcpy( psz_call + 1, psz_function );
  152.         psz_call[ 0 ] = '_';
  153.         p_symbol = _module_getsymbol( handle, psz_call );
  154.         free( psz_call );
  155.     }
  156.  
  157.     return p_symbol;
  158. }
  159.  
  160. /*****************************************************************************
  161.  * module_error: wrapper for dlerror()
  162.  *****************************************************************************
  163.  * This function returns the error message of the last module operation. It
  164.  * returns the string "failed" on systems which do not have a dlerror() like
  165.  * function. psz_buffer can be used to store temporary data, it is guaranteed
  166.  * to be kept intact until the return value of module_error has been used.
  167.  *****************************************************************************/
  168. static const char * module_error( char *psz_buffer )
  169. {
  170. #if defined(SYS_BEOS)
  171.     return "failed";
  172.  
  173. #elif defined(UNDER_CE)
  174.     wchar_t psz_tmp[256];
  175.  
  176.     int i, i_error = GetLastError();
  177.  
  178.     FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  179.                    NULL, i_error, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
  180.                    (LPTSTR) psz_tmp, 256, NULL );
  181.  
  182.     /* Go to the end of the string */
  183.     for( i = 0;
  184.          psz_tmp[i] && psz_tmp[i] != L'\r' && psz_tmp[i] != L'\n';
  185.          i++ ) {};
  186.  
  187.     if( psz_tmp[i] )
  188.     {
  189.         swprintf( psz_tmp + i, L" (error %i)", i_error );
  190.         psz_tmp[ 255 ] = L'\0';
  191.     }
  192.  
  193.     WideCharToMultiByte( CP_ACP, WC_DEFAULTCHAR, psz_tmp, -1,
  194.                          psz_buffer, 256, NULL, NULL );
  195.  
  196.     return psz_buffer;
  197.  
  198. #elif defined(WIN32)
  199.     int i, i_error = GetLastError();
  200.  
  201.     FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  202.                    NULL, i_error, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
  203.                    (LPTSTR) psz_buffer, 256, NULL );
  204.  
  205.     /* Go to the end of the string */
  206.     for( i = 0;
  207.          psz_buffer[i] && psz_buffer[i] != '\r' && psz_buffer[i] != '\n';
  208.          i++ ) {};
  209.  
  210.     if( psz_buffer[i] )
  211.     {
  212.         snprintf( psz_buffer + i, 256 - i, " (error %i)", i_error );
  213.         psz_buffer[ 255 ] = '\0';
  214.     }
  215.  
  216.     return psz_buffer;
  217.  
  218. #else
  219.     return dlerror();
  220.  
  221. #endif
  222. }
  223.  
  224. /*****************************************************************************
  225.  * STORE_SYMBOLS: store known symbols into p_symbols for plugin access.
  226.  *****************************************************************************/
  227.